package com.tcfvic.client;

import java.util.Date;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyUpEvent;
import com.google.gwt.event.dom.client.KeyUpHandler;
import com.google.gwt.event.dom.client.MouseDownEvent;
import com.google.gwt.event.dom.client.MouseDownHandler;
import com.google.gwt.http.client.RequestBuilder;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.AbstractImagePrototype;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.DecoratedStackPanel;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HasVerticalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Tree;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.tcfvic.client.panels.CompanyDetailsForm;
import com.tcfvic.client.panels.FundingSourceDetailsForm;
import com.tcfvic.client.panels.IndustryDetailsForm;
import com.tcfvic.client.panels.JSPDetailsForm;
import com.tcfvic.client.panels.LogsForm;
import com.tcfvic.client.panels.PersonDetailsForm;
import com.tcfvic.client.panels.RTODetailsForm;
import com.tcfvic.client.panels.TrainingDetailsForm;
import com.tcfvic.client.panels.reports.NewReports;
import com.tcfvic.client.panels.reports.PersonReports;
import com.tcfvic.client.panels.tools.UploadKirsteeSpreadsheet;

/**
 * Entry point classes define <code>onModuleLoad()</code>.
 */
public class TCFVic implements EntryPoint {

	/**
	 * The message displayed to the user when the server cannot be reached or
	 * returns an error.
	 */
	private static final String SERVER_ERROR = "An error occurred while "
			+ "attempting to contact the server. Please check your network "
			+ "connection and try again.";
	
	private final PersonReports personReports = new PersonReports();
	private final NewReports newReports = new NewReports();

	/**
	 * Create a remote service proxy to talk to the server-side Greeting
	 * service.
	 */
	private final GreetingServiceAsync greetingService = GWT
			.create(GreetingService.class);

	/**
	 * This is the entry point method.
	 */
	public void onModuleLoad() {
		new RequestBuilder(RequestBuilder.GET,
				"../loginUtil.jsp?action=getInitData&rnd="
						+ new Date().getTime());

		RootPanel.get("windowStack").add(createStackWindow());
		RootPanel.get("windowPanel").clear();
	}

	public Widget createStackWindow() {
		GWT.log("Creating web application GUI", null);
		
//		final PersonServiceAsync personService = GWT
//		.create(PersonService.class);
//		personService.startKeepAliveThread(new AsyncCallback<Void>() {
//			@Override
//			public void onFailure(Throwable caught) {
//			}
//			@Override
//			public void onSuccess(Void result) {
//			}
//		});
		
		// Get the images
		// Images images = (Images) GWT.create(Images.class);

		// Create a new stack panel
		DecoratedStackPanel stackPanel = new DecoratedStackPanel();
		stackPanel.setWidth("100%");

		// Add the person tab
		String workerHeader = getHeaderString("Database entry");
		stackPanel.add(createPersonEditStackPanel(), workerHeader, true);

		// Add the reports tab
		String reportsHeader = getHeaderString("Reports");
		stackPanel.add(createReportsItem(), reportsHeader, true);

		// Add the tools tab
		String toolsHeader = getHeaderString("Tools");
		stackPanel.add(createToolsItem(), toolsHeader, true);

		// Return the stack panel
		stackPanel.ensureDebugId("cwStackPanel");
		return stackPanel;
	}

	/**
	 * Create the {@link Tree} of options.
	 * 
	 * @param images
	 *            the {@link Images} used in the options
	 * @return the {@link Tree} of options
	 */
	private VerticalPanel createPersonEditStackPanel() {
		VerticalPanel panel = new VerticalPanel();
		HTML item = new HTML("Workers");

		panel.add(item);
		item.addMouseDownHandler(new MouseDownHandler() {
			@Override
			public void onMouseDown(MouseDownEvent event) {
				RootPanel.get("windowPanel").clear();
				Widget widgetToShow = new PersonDetailsForm(true).getvSplit();
				RootPanel.get("windowPanel").add(widgetToShow);
				RootPanel.get("windowPanel").setWidgetPosition(widgetToShow,
						200, 30);
			}
		});

		// item = new HTML("Create person");
		// panel.add(item);
		// item.addMouseDownHandler(new MouseDownHandler() {
		// @Override
		// public void onMouseDown(MouseDownEvent event) {
		// RootPanel.get("windowPanel").clear();
		// Widget widgetToShow = new PersonDetailsForm(false).getvSplit();
		// RootPanel.get("windowPanel").add(widgetToShow);
		// RootPanel.get("windowPanel").setWidgetPosition(widgetToShow,
		// 200, 30);
		// }
		// });

		item = new HTML("Companies");
		panel.add(item);
		item.addMouseDownHandler(new MouseDownHandler() {
			@Override
			public void onMouseDown(MouseDownEvent event) {
				RootPanel.get("windowPanel").clear();
				Widget widgetToShow = new CompanyDetailsForm(true).getvSplit();
				RootPanel.get("windowPanel").add(widgetToShow);
				RootPanel.get("windowPanel").setWidgetPosition(widgetToShow,
						200, 30);
			}
		});

//		item = new HTML("Create company");
//		panel.add(item);
//		item.addMouseDownHandler(new MouseDownHandler() {
//			@Override
//			public void onMouseDown(MouseDownEvent event) {
//				RootPanel.get("windowPanel").clear();
//				Widget widgetToShow = new CompanyDetailsForm(false).getvSplit();
//				RootPanel.get("windowPanel").add(widgetToShow);
//				RootPanel.get("windowPanel").setWidgetPosition(widgetToShow,
//						200, 30);
//			}
//		});

		item = new HTML("Funding sources");
		panel.add(item);
		item.addMouseDownHandler(new MouseDownHandler() {
			@Override
			public void onMouseDown(MouseDownEvent event) {
				RootPanel.get("windowPanel").clear();
				Widget widgetToShow = new FundingSourceDetailsForm(true)
						.getvSplit();
				RootPanel.get("windowPanel").add(widgetToShow);
				RootPanel.get("windowPanel").setWidgetPosition(widgetToShow,
						200, 30);
			}
		});

//		item = new HTML("Create funding source");
//		panel.add(item);
//		item.addMouseDownHandler(new MouseDownHandler() {
//			@Override
//			public void onMouseDown(MouseDownEvent event) {
//				RootPanel.get("windowPanel").clear();
//				Widget widgetToShow = new FundingSourceDetailsForm(false)
//						.getvSplit();
//				RootPanel.get("windowPanel").add(widgetToShow);
//				RootPanel.get("windowPanel").setWidgetPosition(widgetToShow,
//						200, 30);
//			}
//		});

		item = new HTML("Training courses");
		panel.add(item);
		item.addMouseDownHandler(new MouseDownHandler() {
			@Override
			public void onMouseDown(MouseDownEvent event) {
				RootPanel.get("windowPanel").clear();
				Widget widgetToShow = new TrainingDetailsForm(true).getvSplit();
				RootPanel.get("windowPanel").add(widgetToShow);
				RootPanel.get("windowPanel").setWidgetPosition(widgetToShow,
						200, 30);
			}
		});

//		item = new HTML("Create training");
//		panel.add(item);
//		item.addMouseDownHandler(new MouseDownHandler() {
//			@Override
//			public void onMouseDown(MouseDownEvent event) {
//				RootPanel.get("windowPanel").clear();
//				Widget widgetToShow = new TrainingDetailsForm(false)
//						.getvSplit();
//				RootPanel.get("windowPanel").add(widgetToShow);
//				RootPanel.get("windowPanel").setWidgetPosition(widgetToShow,
//						200, 30);
//			}
//		});

		item = new HTML("RTOs");
		panel.add(item);
		item.addMouseDownHandler(new MouseDownHandler() {
			@Override
			public void onMouseDown(MouseDownEvent event) {
				RootPanel.get("windowPanel").clear();
				Widget widgetToShow = new RTODetailsForm(true).getvSplit();
				RootPanel.get("windowPanel").add(widgetToShow);
				RootPanel.get("windowPanel").setWidgetPosition(widgetToShow,
						200, 30);
			}
		});

//		item = new HTML("Create RTO");
//		panel.add(item);
//		item.addMouseDownHandler(new MouseDownHandler() {
//			@Override
//			public void onMouseDown(MouseDownEvent event) {
//				RootPanel.get("windowPanel").clear();
//				Widget widgetToShow = new RTODetailsForm(false).getvSplit();
//				RootPanel.get("windowPanel").add(widgetToShow);
//				RootPanel.get("windowPanel").setWidgetPosition(widgetToShow,
//						200, 30);
//			}
//		});

		item = new HTML("JSAPs");
		panel.add(item);
		item.addMouseDownHandler(new MouseDownHandler() {
			@Override
			public void onMouseDown(MouseDownEvent event) {
				RootPanel.get("windowPanel").clear();
				Widget widgetToShow = new JSPDetailsForm(true).getvSplit();
				RootPanel.get("windowPanel").add(widgetToShow);
				RootPanel.get("windowPanel").setWidgetPosition(widgetToShow,
						200, 30);
			}
		});

		item = new HTML("Industries");
		panel.add(item);
		item.addMouseDownHandler(new MouseDownHandler() {
			@Override
			public void onMouseDown(MouseDownEvent event) {
				RootPanel.get("windowPanel").clear();
				Widget widgetToShow = new IndustryDetailsForm(true).getvSplit();
				RootPanel.get("windowPanel").add(widgetToShow);
				RootPanel.get("windowPanel").setWidgetPosition(widgetToShow,
						200, 30);
			}
		});

		item = new HTML("Logs");
		panel.add(item);
		item.addMouseDownHandler(new MouseDownHandler() {
			@Override
			public void onMouseDown(MouseDownEvent event) {
				RootPanel.get("windowPanel").clear();
				Widget widgetToShow = new LogsForm(false).getvSplit();
				RootPanel.get("windowPanel").add(widgetToShow);
				RootPanel.get("windowPanel").setWidgetPosition(widgetToShow,
						200, 30);
			}
		});
		
//		item = new HTML("Create JSP");
//		panel.add(item);
//		item.addMouseDownHandler(new MouseDownHandler() {
//			@Override
//			public void onMouseDown(MouseDownEvent event) {
//				RootPanel.get("windowPanel").clear();
//				Widget widgetToShow = new JSPDetailsForm(false).getvSplit();
//				RootPanel.get("windowPanel").add(widgetToShow);
//				RootPanel.get("windowPanel").setWidgetPosition(widgetToShow,
//						200, 30);
//			}
//		});

		return panel;
	}

	/**
	 * Create the {@link Tree} of options.
	 * 
	 * @param images
	 *            the {@link Images} used in the options
	 * @return the {@link Tree} of options
	 */
	private Tree createReportsItem() {
		Tree panel = new Tree();
//		TreeItem reportPanelRoot = panel.addItem("Data reports");
//		reportPanelRoot.setState(true);

		HTML item = new HTML("New report formats");
//		reportPanelRoot.addItem(item);
		item.addMouseDownHandler(new MouseDownHandler() {
			@Override
			public void onMouseDown(MouseDownEvent event) {
				RootPanel.get("windowPanel").clear();
				Widget widgetToShow = newReports.getContent();
				RootPanel.get("windowPanel").add(widgetToShow);
				RootPanel.get("windowPanel").setWidgetPosition(widgetToShow,
						220, 30);
			}
		});
		panel.addItem(item);

//		item = new HTML("Old report formats");
////		reportPanelRoot.addItem(item);
//		item.addMouseDownHandler(new MouseDownHandler() {
//			@Override
//			public void onMouseDown(MouseDownEvent event) {
//				RootPanel.get("windowPanel").clear();
//				Widget widgetToShow = personReports.getContent();
//				RootPanel.get("windowPanel").add(widgetToShow);
//				RootPanel.get("windowPanel").setWidgetPosition(widgetToShow,
//						220, 30);
//			}
//		});
//		panel.addItem(item);
//		
//		reportPanelRoot = panel.addItem("Query reports");
//
//		item = new HTML("Report XYZ");
//		reportPanelRoot.addItem(item);
//		item.addMouseDownHandler(new MouseDownHandler() {
//			@Override
//			public void onMouseDown(MouseDownEvent event) {
//				RootPanel.get("windowPanel").clear();
//				// Widget widgetToShow = new PersonReports().getContent();
//				// RootPanel.get("windowPanel").add(widgetToShow);
//				// RootPanel.get("windowPanel").setWidgetPosition(widgetToShow,
//				// 220, 30);
//			}
//		});

		return panel;
	}

	/**
	 * Create the {@lindk Tree} of options.
	 * 
	 * @return the {@link Tree} of options
	 */
	private Tree createToolsItem() {
		Tree panel = new Tree();
//		TreeItem reportPanelRoot = panel.addItem("Tools");
//		reportPanelRoot.setState(true);

		HTML item = new HTML("Maintain data");
//		reportPanelRoot.addItem(item);
		item.addMouseDownHandler(new MouseDownHandler() {
			@Override
			public void onMouseDown(MouseDownEvent event) {
				RootPanel.get("windowPanel").clear();
				Widget widgetToShow = new UploadKirsteeSpreadsheet()
						.getContent();
				RootPanel.get("windowPanel").add(widgetToShow);
				RootPanel.get("windowPanel").setWidgetPosition(widgetToShow,
						220, 30);
			}
		});
		panel.addItem(item);
		return panel;
	}

	/**
	 * Get a string representation of the header that includes an image and some
	 * text.
	 * 
	 * @param text
	 *            the header text
	 * @param image
	 *            the {@link AbstractImagePrototype} to add next to the header
	 * @return the header as a string
	 */
	private String getHeaderString(String text) {
		// Add the image and text to a horizontal panel
		HorizontalPanel hPanel = new HorizontalPanel();
		hPanel.setSpacing(0);
		hPanel.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE);
		HTML headerText = new HTML(text);
		headerText.setStyleName("cw-StackPanelHeader");
		hPanel.add(headerText);

		// Return the HTML string for the panel
		return hPanel.getElement().getString();
	}

	/**
	 * This is the entry point method.
	 */
	public void onModuleLoadBackup() {
		final Button sendButton = new Button("Send");
		final TextBox nameField = new TextBox();
		nameField.setText("GWT User");

		// We can add style names to widgets
		sendButton.addStyleName("sendButton");

		// Add the nameField and sendButton to the RootPanel
		// Use RootPanel.get() to get the entire body element
		RootPanel.get("nameFieldContainer").add(nameField);
		RootPanel.get("sendButtonContainer").add(sendButton);

		// Focus the cursor on the name field when the app loads
		nameField.setFocus(true);
		nameField.selectAll();

		// Create the popup dialog box
		final DialogBox dialogBox = new DialogBox();
		dialogBox.setText("Remote Procedure Call");
		dialogBox.setAnimationEnabled(true);
		final Button closeButton = new Button("Close");
		// We can set the id of a widget by accessing its Element
		closeButton.getElement().setId("closeButton");
		final Label textToServerLabel = new Label();
		final HTML serverResponseLabel = new HTML();
		VerticalPanel dialogVPanel = new VerticalPanel();
		dialogVPanel.addStyleName("dialogVPanel");
		dialogVPanel.add(new HTML("<b>Sending name to the server:</b>"));
		dialogVPanel.add(textToServerLabel);
		dialogVPanel.add(new HTML("<br><b>Server replies:</b>"));
		dialogVPanel.add(serverResponseLabel);
		dialogVPanel.setHorizontalAlignment(VerticalPanel.ALIGN_RIGHT);
		dialogVPanel.add(closeButton);
		dialogBox.setWidget(dialogVPanel);

		// Add a handler to close the DialogBox
		closeButton.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				dialogBox.hide();
				sendButton.setEnabled(true);
				sendButton.setFocus(true);
			}
		});

		// Create a handler for the sendButton and nameField
		class MyHandler implements ClickHandler, KeyUpHandler {
			/**
			 * Fired when the user clicks on the sendButton.
			 */
			public void onClick(ClickEvent event) {
				sendNameToServer();
			}

			/**
			 * Fired when the user types in the nameField.
			 */
			public void onKeyUp(KeyUpEvent event) {
				if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) {
					sendNameToServer();
				}
			}

			/**
			 * Send the name from the nameField to the server and wait for a
			 * response.
			 */
			private void sendNameToServer() {
				sendButton.setEnabled(false);
				String textToServer = nameField.getText();
				textToServerLabel.setText(textToServer);
				serverResponseLabel.setText("");
				greetingService.greetServer(textToServer,
						new AsyncCallback<String>() {
							public void onFailure(Throwable caught) {
								// Show the RPC error message to the user
								dialogBox
										.setText("Remote Procedure Call - Failure");
								serverResponseLabel
										.addStyleName("serverResponseLabelError");
								serverResponseLabel.setHTML(SERVER_ERROR);
								dialogBox.center();
								closeButton.setFocus(true);
							}

							public void onSuccess(String result) {
								dialogBox.setText("Remote Procedure Call");
								serverResponseLabel
										.removeStyleName("serverResponseLabelError");
								serverResponseLabel.setHTML(result);
								dialogBox.center();
								closeButton.setFocus(true);
							}
						});
			}
		}

		// Add a handler to send the name to the server
		MyHandler handler = new MyHandler();
		sendButton.addClickHandler(handler);
		nameField.addKeyUpHandler(handler);
	}
}
